using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;

namespace NUtil.lists {
    public class ImmutableList<T> : IList<T> {

        public ImmutableList(IList<T> source) {
            this.source = source;
        }

        public int IndexOf(T item) {
            return source.IndexOf(item);
        }

        public void Insert(int index, T item) {
            throw notSupportedException(MethodBase.GetCurrentMethod());
        }

        public void RemoveAt(int index) {
            throw notSupportedException(MethodBase.GetCurrentMethod());
        }

        public T this[int index] {
            get { return source[index]; }
            set { source[index] = value; }
        }

        public void Add(T item) {
            throw notSupportedException(MethodBase.GetCurrentMethod());
        }

        public void Clear() {
            throw notSupportedException(MethodBase.GetCurrentMethod());
        }

        public bool Contains(T item) {
            return source.Contains(item);
        }

        public void CopyTo(T[] array, int arrayIndex) {
            source.CopyTo(array, arrayIndex);
        }

        public bool Remove(T item) {
            throw notSupportedException(MethodBase.GetCurrentMethod());
        }

        public int Count {
            get { return source.Count; }
        }

        public bool IsReadOnly {
            get { return source.IsReadOnly; }
        }

        public IEnumerator<T> GetEnumerator() {
            return source.GetEnumerator();
        }
        
        IEnumerator IEnumerable.GetEnumerator() {
            throw new NotImplementedException();
        }
        private IList<T> source;
        private string exceptionMessage = "{0} operation is not supported on " + typeof(ImmutableList<T>).Name;

        private NotSupportedException notSupportedException(MethodBase methodBase)
        {
            return new NotSupportedException(string.Format(this.exceptionMessage, methodBase.Name));
        }


    }
}